package ldh.im.fxgui.controller;

import com.jfoenix.controls.JFXDialog;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import ldh.im.dto.enmus.MessageType;
import ldh.im.fxbase.pojo.DbMessage;
import ldh.im.fxbase.pojo.ImGroup;
import ldh.im.fxbase.pojo.ext.MessageStatus;
import ldh.im.fxbase.pojo.User;
import ldh.im.fxbase.richtext.TextItem;
import ldh.im.fxbase.service.AudioStreamService;
import ldh.im.fxbase.util.BeanFactory;
import ldh.im.fxbase.util.DialogUtil;
import ldh.im.fxgui.controller.handler.*;
import ldh.im.fxbase.richtext.ImTextArea;
import ldh.im.fxbase.dao.MessageDao;
import ldh.im.fxbase.service.AudioService;
import ldh.im.fxbase.util.ThreadPoolUtil;
import ldh.im.fxgui.util.UiUtil;
import org.fxmisc.flowless.VirtualizedScrollPane;

import java.io.File;
import java.net.URL;
import java.text.NumberFormat;
import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Logger;

public class SendMessageController implements Initializable {

    private static final Logger LOGGER = Logger.getLogger(SendMessageController.class.getName());

    @FXML private Pane editorPane;
    @FXML private Pane messageListPane;
    @FXML private StackPane root;
    @FXML private Label titleLabel;

    private MessageController messageController;
    private JFXDialog audioDialog = null;

    private SendMessageHandler sendMessageHandler;

    private ImTextArea messageEditor;
    private ImGroup currentMitem;
    private MessageDao messageDao = BeanFactory.getInstance().getBean(MessageDao.class);
    private AudioStreamService audioService = new AudioStreamService(System.getProperty("user.dir") + "/doc/audio");
    private FileChooser fileChooser = new FileChooser();

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        messageEditor = new ImTextArea();
        VirtualizedScrollPane scrollPane = new VirtualizedScrollPane(messageEditor);
        editorPane.getChildren().add(scrollPane);

//        sendMessageHandler = new SendMessageVBoxHandler();
        sendMessageHandler = new SendMessageVirtualFlowHandler();
//        sendMessageHandler = new SendMessageListViewHandler();

        messageListPane.getChildren().add(sendMessageHandler.createMessagePaneNode());

        initHtmlEditor();

        messageEditor.requestFocus();

        fileChooser.setInitialDirectory(new File(System.getProperty("user.dir")));
        fileChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("im文件上传器",
                Arrays.asList("*.txt", "*.jpg", "*.png", "*.gif", "*.svg", "*.vsd", "*.gz", "*.zip", "*.rar",
                        "*.doc", "*.docx",  "*.xls", "*.xlsx", "*.ppt")));
    }

    public DbMessage getMessage(Long id) {
        for(DbMessage m : sendMessageHandler.getItems()) {
            if (m.getId().equals(id)) return m;
        }
        return null;
    }

    public void setMessageController(MessageController messageController) {
        this.messageController = messageController;
    }

    public void loadMessageDatas() {
        ThreadPoolUtil.submit(()->{
            try {
                List<DbMessage> messages = messageDao.getMessagesByImGroupId(currentMitem.getId(), 100);
                if (messages.size() < 1) return;
                messages.forEach(m-> {
                    m.setImGroup(currentMitem);
                    User user = initUser(currentMitem.getUserId());
                    m.setFromUser(user);
                });
                Platform.runLater(()->{
                    sendMessageHandler.addMessages(messages);
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public void setMItem(ImGroup mItem) {
        this.currentMitem = mItem;
        titleLabel.setText(mItem.getName());
    }

    @FXML
    public void sendMsg(ActionEvent actionEvent) {
        String msg = messageEditor.getData();
        if (msg.equals("")) return;
        if (messageEditor.isTooLength(msg)) {
            DialogUtil.alert("警告", "文本超长", "填入的数字太长");
            return;
        }
//        int richTextType = ImTextArea.richTextType(msg);
//        MessageType messageType = richTextType == 1 ? MessageType.Text : (richTextType == 2 ? MessageType.Image : MessageType.RichText);
//        if (richTextType == 2) {
//            msg = ImageTextItem.parseUrl(msg);
//            if (msg == null) return;
//        }
        Long start = System.currentTimeMillis();
        List<Object> messages = ImTextArea.split(msg);
        List<DbMessage> dbMessages = new ArrayList<>();
        for(Object obj : messages) {
            if (obj instanceof String) {
                DbMessage textMessage = createMessage(((String) obj).toLowerCase(), MessageType.RichText);
                dbMessages.add(textMessage);
            } else {
                TextItem textItem = (TextItem) obj;
                DbMessage textMessage = createMessage(textItem.getData(), MessageType.Image);
                dbMessages.add(textMessage);
            }
        }
        System.out.println("time1:" + (System.currentTimeMillis() - start));
        sendMessageHandler(dbMessages, this::sendMessages);
    }

    // 显示Emoji选择面板
    @FXML public void showEmojiPane(ActionEvent actionEvent) {
        Button b = (Button) actionEvent.getSource();
        UiUtil.getEmojiPane().show(b, emojiSpan->{
            messageEditor.insertEmoji(emojiSpan);
//            HtmlEditorUtil.insertHtml(messageEditor, emojiSpan);
        });
    }

    // 上传文件
    @FXML public void uploadFile(ActionEvent actionEvent) {
        File file = fileChooser.showOpenDialog(root.getScene().getWindow());
        if (file == null) return;
        DbMessage textMessage = createMessage(file.getName(), MessageType.File);
        textMessage.getMessageExt().setLocalDir(file.getParent());
        textMessage.getMessageExt().setRemote(false);
        textMessage.getMessageExt().setSize(file.length());
        textMessage.initExt();
        List<DbMessage> dbMessages = new ArrayList<>();
        dbMessages.add(textMessage);
        sendMessageHandler(dbMessages, this::sendMessages);
    }

    // 截图
    @FXML public void cut(ActionEvent actionEvent) {
        UiUtil.getScreenCapturePane().show(image->{
            messageEditor.insertImage(image);
//            HtmlEditorUtil.insertHtml(messageEditor, emojiSpan);
        });
    }

    // 历史信息
    @FXML public void historyMessagePane(ActionEvent actionEvent) {

    }

    // 语音聊天
    @FXML public void voicePane(ActionEvent actionEvent) {
        if (audioDialog == null) {
            JFXDialogLayout messge = new JFXDialogLayout();
            VBox vBox = new VBox();
            vBox.setSpacing(10);
            vBox.setAlignment(Pos.CENTER);
            Text text =  new Text();
            text.setFont(Font.font(20));
            audioService.getRecordTimeProperty().addListener(l->{
                long time = audioService.getRecordTime();
                NumberFormat numberFormat = NumberFormat.getNumberInstance();
                numberFormat.setMaximumFractionDigits(3);
                text.setText(numberFormat.format((double)time/1000) + " 秒");
            });
            Button b = new Button("Start");
            b.setStyle("-fx-background-color: cadetblue;"+
                            "-fx-background-radius: 20;"+
                            "-fx-text-fill: antiquewhite;"+
                            "-fx-font-family: 'Microsoft YaHei UI';"+
                            "-fx-font-size: 20"
            );
            b.setOnAction(e->{
                if (b.getText().equals("Start")) {
                    audioService.startRecord();
                    b.setText("Stop");
                } else {
                    b.setText("Start");
                    audioService.stopRecord();

                    File file = new File(audioService.getAudioFile());
                    DbMessage dbMessage = createMessage(file.getName(), MessageType.Audio);
                    dbMessage.getMessageExt().setSize(audioService.getRecordTime());
                    dbMessage.getMessageExt().setLocalDir(file.getParent());
                    dbMessage.getMessageExt().setRemote(false);
                    dbMessage.initExt();

                    List<DbMessage> dbMessages = Arrays.asList(dbMessage);
                    sendMessageHandler(dbMessages, this::sendMessages);

                    audioDialog.close();
                }

            });
            vBox.getChildren().addAll(text, b);
            messge.setBody(vBox);
            audioDialog = new JFXDialog(root, messge, JFXDialog.DialogTransition.CENTER);
            audioDialog.setPrefSize(100, 80);
        }
        audioDialog.show();
        audioService.getRecordTimeProperty().set(0);
    }

    private List<DbMessage> createTextMessage(ImGroup mItem, int num) {
        List<DbMessage> messages = new ArrayList(num);
        for(int i=0; i<num; i++) {
            DbMessage textMessage = new DbMessage();
            textMessage.setId((long)i);
            User fromUser = new User();
            fromUser.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
            fromUser.setUserName(mItem.getName());

            textMessage.setFromUser(fromUser);
            textMessage.setContent("hello world!!!" + i);
            messages.add(textMessage);
        }
        return messages;
    }

    private void initHtmlEditor() {
//        messageEditor.getEngine().loadContent(UiUtil.getInitWebViewHtml());
    }

    private DbMessage createMessage(String msg, MessageType messageType) {
        DbMessage textMessage = new DbMessage();
        textMessage.setServerId("");
//        textMessage.setGroupId(currentMitem.getId());
        textMessage.setContent(msg);
        textMessage.setMessageType(messageType);
        textMessage.setStatus(MessageStatus.created);
        textMessage.setImGroup(currentMitem);
        textMessage.setFromUser(initUser(currentMitem.getUserId()));
        return textMessage;
    }

    // 消息发送处理
    private void sendMessageHandler(List<DbMessage> dbMessages, Consumer<List<DbMessage>> consumer) {
        long start = System.currentTimeMillis();
        messageEditor.clear();

        sendMessageHandler.addMessages(dbMessages);

        System.out.println("time2:" + (System.currentTimeMillis() - start));
        ThreadPoolUtil.submit(()->{
            try {
                Platform.runLater(()->{
                    currentMitem.setUpdateTime(new Date());
                    messageController.reloadMItem(currentMitem, false);
                });
                messageDao.saveMessages(dbMessages);
                if (consumer != null) {
                    consumer.accept(dbMessages);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        initHtmlEditor();
        System.out.println("time3:" + (System.currentTimeMillis() - start));
    }

    // 发送消息
    private void sendMessages(List<DbMessage> dbMessages) {
        // todo
    }

    private User initUser(Long fromUserId) {
        User user = new User();
        user.setId(fromUserId);
        user.setHeadImg(this.getClass().getResource("/imgs/head.jpg").toExternalForm());
        return user;
    }
}
